/*
 * $RCSfile: Backup.java,v $$
 * $Revision: 1.1 $
 * $Date: 2013-12-15 $
 *
 * Copyright (C) 2008 Skin, Inc. All rights reserved.
 *
 * This software is the proprietary information of Skin, Inc.
 * Use is subject to license terms.
 */
package com.skin.webcat.exchange;

import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.skin.webcat.database.Table;
import com.skin.webcat.database.handler.TableHandler;

/**
 * <p>Title: Backup</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2006</p>
 * @author xuesong.net
 * @version 1.0
 */
public class Backup implements Runnable {
    private String target;
    private Connection connection;
    private DataExport dataExport;
    private static final Logger logger = LoggerFactory.getLogger(Backup.class);

    /**
     * default
     */
    public Backup() {
    }

    /**
     * @param connection
     * @param target
     */
    public Backup(Connection connection, String target) {
        this.target = target;
        this.connection = connection;
    }

    /**
     * @param tableName
     * @param target
     * @throws Exception
     */
    public void backup(String tableName, File target) throws Exception {
        this.dataExport.setConnection(this.connection);
        this.dataExport.execute(tableName, target);
    }

    /**
     * @param target
     * @throws Exception
     */
    public void execute(File target) throws Exception {
        if(logger.isInfoEnabled()) {
            logger.info("Backup start...");
            logger.info("Backup.target: " + target.getAbsolutePath());
        }

        Exception exception = null;
        File lock = new File(target, "LOCK");

        if(lock.exists() == false) {
            try {
                if(target.exists() == false) {
                    target.mkdirs();
                }

                lock.createNewFile();
                TableHandler tableHandler = new TableHandler(this.connection);
                List<Table> tableList = tableHandler.getTableList("%", new String[]{"TABLE"}, false);

                if(tableList != null) {
                    this.dataExport.setConnection(this.connection);

                    for(Table table : tableList) {
                        String tableName = table.getTableName();
                        this.dataExport.execute(tableName, new File(target, tableName + ".sql"));

                        if(logger.isInfoEnabled()) {
                            logger.info("backup table [" + tableName + "] successful !");
                        }
                    }
                }
                else {
                    if(logger.isInfoEnabled()) {
                        logger.info("no table to backup !");
                    }
                }
            }
            catch(Exception e) {
                exception = e;
            }

            try {
                lock.delete();
            }
            catch(Exception e) {
                e.printStackTrace();
            }
        }
        else {
            if(logger.isInfoEnabled()) {
                logger.info("Backup is running...");
            }
        }

        if(logger.isInfoEnabled()) {
            logger.info("Backup complete !");
        }

        if(exception != null) {
            throw exception;
        }
    }

    /**
     * 
     */
    @Override
    public void run() {
        try {
            this.execute(new File(this.target));
        }
        catch(Throwable t) {
            t.printStackTrace();
        }
        finally {
            if(this.connection != null) {
                try {
                    this.connection.close();
                }
                catch(SQLException e) {
                }
            }
        }
    }

    /**
     * @return the target
     */
    public String getTarget() {
        return this.target;
    }

    /**
     * @param target the target to set
     */
    public void setTarget(String target) {
        this.target = target;
    }
    
    /**
     * @return the dataExport
     */
    public DataExport getDataExport() {
        return this.dataExport;
    }

    /**
     * @param dataExport the dataExport to set
     */
    public void setDataExport(DataExport dataExport) {
        this.dataExport = dataExport;
    }

    /**
     * @return the connection
     */
    public Connection getConnection() {
        return this.connection;
    }

    /**
     * @param connection the connection to set
     */
    public void setConnection(Connection connection) {
        this.connection = connection;
    }
}
